
import java.util.Vector;
import sun.misc.Sort;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author ALICIA
 */
public final class StdStats {

    public StdStats() { }

    /**
      * Return maximum value in array, -infinity if no such value.
      */
    public static Double max(Double[] a) {
        Double max = Double.NEGATIVE_INFINITY;
        for (int i = 0; i < a.length; i++) {
            if (a[i] > max) max = a[i];
        }
        return max;
    }

    /**
      * Return maximum value in subarray a[lo..hi], -infinity if no such value.
      */
    public static Double max(Double[] a, int lo, int hi) {
        if (lo < 0 || hi >= a.length || lo > hi)
            throw new RuntimeException("Subarray indices out of bounds");
        Double max = Double.NEGATIVE_INFINITY;
        for (int i = lo; i <= hi; i++) {
            if (a[i] > max) max = a[i];
        }
        return max;
    }

   /**
     * Return maximum value of array, Integer.MIN_VALUE if no such value
     */
    public static int max(int[] a) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < a.length; i++) {
            if (a[i] > max) max = a[i];
        }
        return max;
    }
    
    public Double max(Vector<Double> a) {
        Double max = Double.MIN_VALUE;
        for (int i = 0; i < a.size(); i++) {
            if (a.get(i) > max) max = a.get(i);
        }
        return max;
    }


   /**
     * Return minimum value in array, +infinity if no such value.
     */
    public static Double min(Double[] a) {
        Double min = Double.POSITIVE_INFINITY;
        for (int i = 0; i < a.length; i++) {
            if (a[i] < min) min = a[i];
        }
        return min;
    }

    /**
      * Return minimum value in subarray a[lo..hi], +infinity if no such value.
      */
    public static Double min(Double[] a, int lo, int hi) {
        if (lo < 0 || hi >= a.length || lo > hi)
            throw new RuntimeException("Subarray indices out of bounds");
        Double min = Double.POSITIVE_INFINITY;
        for (int i = lo; i <= hi; i++) {
            if (a[i] < min) min = a[i];
        }
        return min;
    }

   /**
     * Return minimum value of array, Integer.MAX_VALUE if no such value
     */
    public static int min(int[] a) {
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < a.length; i++) {
            if (a[i] < min) min = a[i];
        }
        return min;
    }
    public  Double min(Vector<Double> a) {
        Double min = Double.POSITIVE_INFINITY;
        for (int i = 0; i < a.size(); i++) {
            if (a.get(i) < min) min = a.get(i);
        }
        return min;
    }

   /**
     * Return average value in array, NaN if no such value.
     */
    public static Double mean(Double[] a) {
        if (a.length == 0) return Double.NaN;
        Double sum = sum(a);
        return sum / a.length;
    }
    public static Double mean(Vector<Double> a) {
        if (a.size() == 0) return Double.NaN;
        Double sum = sum(a);
        return sum / a.size();
    }

   /**
     * Return average value in subarray a[lo..hi], NaN if no such value.
     */
    public static Double mean(Double[] a, int lo, int hi) {
        int length = hi - lo + 1;
        if (lo < 0 || hi >= a.length || lo > hi)
            throw new RuntimeException("Subarray indices out of bounds");
        if (length == 0) return Double.NaN;
        Double sum = sum(a, lo, hi);
        return sum / length;
    }

   /**
     * Return average value in array, NaN if no such value.
     */
    public static Double mean(int[] a) {
        if (a.length == 0) return Double.NaN;
        Double sum = 0.0;
        for (int i = 0; i < a.length; i++) {
            sum = sum + a[i];
        }
        return sum / a.length;
    }

   /**
     * Return sample variance of array, NaN if no such value.
     */
    public static Double var(Double[] a) {
        if (a.length == 0) return Double.NaN;
        Double avg = mean(a);
        Double sum = 0.0;
        for (int i = 0; i < a.length; i++) {
            sum += (a[i] - avg) * (a[i] - avg);
        }
        return sum / (a.length - 1);
    }
    public static Double var(Vector<Double> a) {
        if (a.size() == 0) return Double.NaN;
        Double avg = mean(a);
        Double sum = 0.0;
        for (int i = 0; i < a.size(); i++) {
            sum += (a.get(i) - avg) * (a.get(i) - avg);
        }
        return sum / (a.size() - 1);
    }

   /**
     * Return sample variance of subarray a[lo..hi], NaN if no such value.
     */
    public static Double var(Double[] a, int lo, int hi) {
        int length = hi - lo + 1;
        if (lo < 0 || hi >= a.length || lo > hi)
            throw new RuntimeException("Subarray indices out of bounds");
        if (length == 0) return Double.NaN;
        Double avg = mean(a, lo, hi);
        Double sum = 0.0;
        for (int i = lo; i <= hi; i++) {
            sum += (a[i] - avg) * (a[i] - avg);
        }
        return sum / (length - 1);
    }

   /**
     * Return sample variance of array, NaN if no such value.
     */
    public static Double var(int[] a) {
        if (a.length == 0) return Double.NaN;
        Double avg = mean(a);
        Double sum = 0.0;
        for (int i = 0; i < a.length; i++) {
            sum += (a[i] - avg) * (a[i] - avg);
        }
        return sum / (a.length - 1);
    }

   /**
     * Return population variance of array, NaN if no such value.
     */
    public static Double varp(Double[] a) {
        if (a.length == 0) return Double.NaN;
        Double avg = mean(a);
        Double sum = 0.0;
        for (int i = 0; i < a.length; i++) {
            sum += (a[i] - avg) * (a[i] - avg);
        }
        return sum / a.length;
    }

   /**
     * Return population variance of subarray a[lo..hi],  NaN if no such value.
     */
    public static Double varp(Double[] a, int lo, int hi) {
        int length = hi - lo + 1;
        if (lo < 0 || hi >= a.length || lo > hi)
            throw new RuntimeException("Subarray indices out of bounds");
        if (length == 0) return Double.NaN;
        Double avg = mean(a, lo, hi);
        Double sum = 0.0;
        for (int i = lo; i <= hi; i++) {
            sum += (a[i] - avg) * (a[i] - avg);
        }
        return sum / length;
    }


   /**
     * Return sample standard deviation of array, NaN if no such value.
     */
    public static Double stddev(Double[] a) {
        return Math.sqrt(var(a));
    }
    public static Double stddev(Vector<Double> a) {
        return Math.sqrt(var(a));
    }

   /**
     * Return sample standard deviation of subarray a[lo..hi], NaN if no such value.
     */
    public static Double stddev(Double[] a, int lo, int hi) {
        return Math.sqrt(var(a, lo, hi));
    }

   /**
     * Return sample standard deviation of array, NaN if no such value.
     */
    public static Double stddev(int[] a) {
        return Math.sqrt(var(a));
    }

   /**
     * Return population standard deviation of array, NaN if no such value.
     */
    public static Double stddevp(Double[] a) {
        return Math.sqrt(varp(a));
    }

   /**
     * Return population standard deviation of subarray a[lo..hi], NaN if no such value.
     */
    public static Double stddevp(Double[] a, int lo, int hi) {
        return Math.sqrt(varp(a, lo, hi));
    }

   /**
     * Return sum of all values in array.
     */
    public static Double sum(Double[] a) {
        Double sum = 0.0;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        return sum;
    }
    public static Double sum(Vector<Double> a) {
        Double sum = 0.0;
        for (int i = 0; i < a.size(); i++) {
            sum += a.get(i);
        }
        return sum;
    }

   /**
     * Return sum of all values in subarray a[lo..hi].
     */
    public static Double sum(Double[] a, int lo, int hi) {
        if (lo < 0 || hi >= a.length || lo > hi)
            throw new RuntimeException("Subarray indices out of bounds");
        Double sum = 0.0;
        for (int i = lo; i <= hi; i++) {
            sum += a[i];
        }
        return sum;
    }

   /**
     * Return sum of all values in array.
     */
    public static int sum(int[] a) {
        int sum = 0;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        return sum;
    }

    public Double corrPer(Vector<Double> a,Vector<Double> b)
    {
        Double ab=0.0;
        Double asqrt=0.0;
        Double bsqrt=0.0;
        for(int y=0;y<a.size();y++)
        {
            ab+=(a.get(y)*b.get(y));
            asqrt+= Math.pow(a.get(y), 2.0);
            bsqrt+= Math.pow(b.get(y), 2.0);
        }
        //medias aritmetica
        Double xmean=sum(a)/a.size();
        Double ymean=sum(b)/b.size();
        //calculo de covarianza
        Double cova=(ab/a.size())-(xmean*ymean);
        //desviacion
        Double desvx=Math.sqrt((asqrt/a.size())-Math.pow(xmean, 2.0));
        Double desvy=Math.sqrt((bsqrt/b.size())-Math.pow(ymean, 2.0));
        //
        return cova/(desvx*desvy);

        
    }
    //verificar mala implementacion
    public Double corrRank(Vector<Double> A, Vector<Double> B){

        
    Integer i;
    Integer len = A.size();
    Double correlation;
    Double XX = 0.0; //normally would be an outer-product matrix
    Double[] runningSum = new Double[2]; //since you have two variables (A and B)
    Double[] x2 = new Double[2];
    Double[] stdev = new Double[2];
    x2[0]=0.0;
    x2[1]=0.0;
    runningSum[0] =0.0;
    runningSum[1] =0.0;
for (i = 0; i < len; ++i)
{
   XX += A.get(i)* B.get(i);
   //System.out.println(Math.pow(A.get(i),2.0)+"asdasd");
   x2[0] = x2[0] +  Math.pow(A.get(i),2.0);
      
   x2[1] += Math.pow(B.get(i), 2.0);
   runningSum[0] += A.get(i);
   runningSum[1] += B.get(i);
}

// Compute mu
runningSum[0] = runningSum[0] / len;
runningSum[1] = runningSum[1] / len;

// Compute std deviation (bias-corrected)
stdev[0] = Math.sqrt(x2[0] - len * Math.pow(runningSum[0], 2.0)) / (len - 1);
stdev[1] = Math.sqrt(x2[1] - len * Math.pow(runningSum[1], 2.0)) / (len - 1);

// now compute correlation coefficient
correlation = (XX - (len * runningSum[0] * runningSum[1])) / (len - 1);
correlation = correlation / (stdev[0] * stdev[1]);
    return correlation;
    }

   /**
     * Plot points (i, a[i]) to standard draw.
     */
  /*  public static void plotPoints(Double[] a) {
        int N = a.length;
        StdDraw.setXscale(0, N-1);
        StdDraw.setPenRadius(1.0 / (3.0 * N));
        for (int i = 0; i < N; i++) {
            StdDraw.point(i, a[i]);
        }
    }

   /**
     * Plot line segments connecting points (i, a[i]) to standard draw.
     */
  /*  public static void plotLines(Double[] a) {
        int N = a.length;
        StdDraw.setXscale(0, N-1);
        StdDraw.setPenRadius();
        for (int i = 1; i < N; i++) {
            StdDraw.line(i-1, a[i-1], i, a[i]);
        }
    }

   /**
     * Plot bars from (0, a[i]) to (i, a[i]) to standard draw.
     */
  /*  public static void plotBars(Double[] a) {
        int N = a.length;
        StdDraw.setXscale(0, N-1);
        for (int i = 0; i < N; i++) {
            StdDraw.filledRectangle(i, a[i]/2, .25, a[i]/2);
        }
    }


   /**
     * Test client.
     * Convert command-line arguments to array of Doubles and call various methods.
     */
 /*   public static void main(String[] args) {
        Double[] a = StdArrayIO.readDouble1D();
        StdOut.printf("       min %7.3f\n", min(a));
        StdOut.printf("      mean %7.3f\n", mean(a));
        StdOut.printf("       max %7.3f\n", max(a));
        StdOut.printf("   std dev %7.3f\n", stddev(a));
    }*/
}



